home *** CD-ROM | disk | FTP | other *** search
- {textio.pas -- demo of input/output "tricks" for turbo pascal }
- (*
- demonstration of useful text i/o features with turbo pascal:
- 1. large text buffers for speedier handling when needed
- 2. complete seek function for text files
- 3. write formatted output to a string variable
- 4. read contents of a string variable as formatted input
-
- language: turbo pascal macintosh "{, comments "
- or: turbo pascal 4.0 ibm. "{. comments "
-
- by d.g.gilbert
- dogStar software
- po box 302, bloomington, in 47402
- compuserve 71450,1570
- *)
-
- PROGRAM turboTextIO;
- {$R-} { Turn off range checking }
- {$I-} { Turn off I/O error checking }
-
- {.ibm} USES DOS;
- (*{,mac} USES memTypes, quickDraw, osIntf, toolIntf;*)
-
- CONST
- forOutput = true; forInput = false;
- TYPE
- (* pointer = ^integer; {,mac} *)
- chars = PACKED ARRAY [0..maxint] OF char;
- bufferPtr = ^chars;
- procPtr = pointer;
-
-
- {.turbo pascal ibm text file record}
- tpFileRec = RECORD
- handle : word;
- mode : word;
- fBufSize : word;
- private : word;
- fBufPos : word;
- fBufEnd : word;
- fBuffer : bufferPtr;
- openFunc : procptr;
- inOutFunc: procptr;
- flushFunc: procptr;
- closeFunc: procptr;
- userdata : PACKED ARRAY[1..16] OF byte;
- name : PACKED ARRAY [0..79] OF char;
- tbuffer : PACKED ARRAY [0..127] OF char; { default buffer}
- END;
- (*
- {, turbo pascal mac file record }
- tpFileRec = RECORD
- fInpFlag: boolean;
- fOutFlag: boolean;
- fRefNum : integer;
- fVrefNum: integer;
- fBufSize: integer;
- fBufPos : integer;
- fBufEnd : integer;
- fBuffer : bufferPtr;
- fInOutProc: procPtr;
- END;
- *)
-
-
-
- FUNCTION openText( VAR f: text;
- fname : STRING;
- output: boolean; {true if want a rewrite }
- bufsize: integer
- ): boolean; { true if opened successfully }
-
- VAR abuf: pointer;
- err: integer;
- BEGIN
-
- {. ibm}
- assign( f, fname);
- { now change buf to the size we want}
- WITH tpfilerec(f) DO BEGIN
- getmem( abuf, bufsize);
- fBuffer:= abuf;
- fBufSize:= bufsize;
- END;
- IF output THEN rewrite( f) ELSE reset(f);
- err:= ioresult;
- IF err <> 0 THEN dispose(abuf); {forget it}
- openText:= err = 0;
- (*
- {, mac}
- IF output THEN rewrite( f, fname, bufsize)
- ELSE reset( f, fname, bufsize);
- openText:= ioresult = 0;
- *)
- END; {openText}
-
- PROCEDURE closeText( VAR f: text);
- VAR abuf: pointer;
- BEGIN
- {.ibm} abuf:= tpfilerec(f).fBuffer;
- close(f);
- {.ibm} dispose(abuf);
- END;
-
-
- {.ibm}
- CONST strFileName = '$%#temp.tmp';
- CONST needStrFile: boolean = true; {1st time open tempFile }
- VAR strFile : text; {.ibm -- save file i/o information for strIO}
-
- PROCEDURE openStrIO( VAR f: text; VAR s: STRING; out: boolean);
- { assign file input/output to string. }
- BEGIN
-
- {.ibm}
- IF needStrFile THEN BEGIN
- assign(strFile, strFileName);
- rewrite(strFile); {<< need this to fill in valid turbo proc ptrs}
- tpfilerec(f):= tpfilerec(strFile);
- close(strFile); erase(strFile);
- tpfilerec(strfile):= tpfilerec(f);
- needStrFile:= false;
- END;
- tpfilerec(f):= tpfilerec(strFile);
- WITH tpFileRec(f) DO BEGIN
- IF out THEN mode:= fmOutput ELSE mode:= fmInput;
- END;
- (*
- {,mac}
- WITH tpfilerec(f) DO BEGIN
- fInpFlag:= NOT out;
- fOutFlag:= out;
- fRefNum:= 1; {dummy}
- fVrefNum:= 1;
- fInOutProc:= NIL;
- END;
- *)
- {both}
- WITH tpFileRec(f) DO BEGIN
- fBuffer:= @s[1];
- fBufSize:= 255; {assume it is full string}
- IF out THEN fBufEnd:= fBufSize
- ELSE fBufEnd:= length(s);
- fBufPos:= 0;
- END;
- END; {openStrIO}
-
- PROCEDURE closeStrIO( VAR f: text; VAR s: STRING);
- { close stringiO: get length }
- VAR err: integer;
- BEGIN
- s[0]:= chr( tpFileRec(f).fBufPos);
- END; {closeStrIO}
-
-
- TYPE seekType = (seek_set, seek_cur, seek_end);
-
- {.ibm version}
- PROCEDURE seekText( VAR f: text; offset: longInt;
- seekFrom : seektype);
- { seek for textfiles }
- VAR
- count: longint;
- iseek: integer;
- err : integer;
- uf : FILE; {.ibm}
-
-
- FUNCTION msDosSeek( fh:integer; index:longint; fromwhere:seekType):integer;
- { move file pointer to byte index (hiIndx,lowIndx), respective to fromWhere }
- TYPE words = ARRAY [0..1] OF word;
- VAR reg : registers;
- BEGIN
- reg.ah:= $42; { move f^ }
- reg.al:= ord(fromwhere);
- reg.cx:= words(index)[1]; {hiindex}
- reg.dx:= words(index)[0]; {lowIndex}
- reg.bx := fh;
- msdos(reg);
- IF 0 = (reg.flags AND $01) THEN msdosSeek:= 0 ELSE msDosSeek:= reg.ax;
- END; { msDosSeek }
-
- BEGIN
- {.ibm}
- WITH tpFileRec(f) DO
- IF handle<0 THEN {nada - not a disk file}
- ELSE BEGIN
- IF mode = fmOutput THEN BEGIN
- { flush buffer to disk if seek on output file}
- move(f, uf, sizeof(f)); { need right file type for blockwrite}
- fileRec(uf).recsize:= 1;
- blockwrite( uf, fBuffer^, fBufPos, err);
- fBufPos:= 0;
- END
- ELSE IF seekFrom = seek_cur THEN
- offset:= offset - fBufEnd + fBufPos;
- IF 0 = msdosSeek( handle, offset, seekFrom) THEN BEGIN
- fBufPos:= 0; fBufEnd:= 0; {next read/write will fill buffer as needed}
- END;
- END;
- END; {seekText}
- (*******
- {, mac version }
- PROCEDURE seekText( VAR f: text; offset: longInt;
- seekFrom : seektype);
- { seek for textfiles }
- VAR
- count: longint;
- iseek: integer;
- err : integer;
- BEGIN
- CASE seekFrom OF
- seek_set : iseek:= fsFromStart; {offset from 0}
- seek_cur : iseek:= fsFromMark;
- seek_end : iseek:= fsFromLEOF;
- END;
- WITH tpFileRec(f) DO
- IF fRefNum=0 THEN {not a disk file}
- ELSE BEGIN
- IF fOutFlag THEN BEGIN { flush buffer to disk if seek on output file}
- count:= fBufPos;
- err:= fsWrite( fRefNum, count, ptr(fBuffer));
- fBufPos:= 0;
- END
- ELSE IF seekFrom = seek_cur THEN
- offset:= offset - fBufEnd + fBufPos;
- IF 0 = setFpos( fRefNum, iseek, offset) THEN BEGIN
- fBufEnd:= 0; fBufPos:= 0;
- END;
- END;
- END; {seekText}
- ***********)
-
-
-
- { test }
- CONST
- BUFSIZE = 32000; { a big text buffer}
- VAR
- f: text;
- s: STRING;
- i: integer;
- r: real;
- b: boolean;
- index: longint;
- BEGIN
- writeln;
- writeln('useful Turbo Pascal Text I/O features');
- writeln('by d.g.gilbert, Dec87');
- writeln;
-
- write('File to Open: '); readln( s);
- IF openText( f, s, forInput, BUFSIZE) THEN BEGIN
- REPEAT
- write('Seek type 0)set, 1)current, 2)end : '); readln( i);
- IF i IN [0..2] THEN BEGIN
- write('Seek index: '); readln( index);
- seekText( f, index, seekType(i));
- readln( f, s); writeln('> ',s);
- END;
- UNTIL NOT (i IN [0..2]);
- closeText( f);
- END;
-
- writeln('Testing formatted output to a string');
- i:= 99; r:= 12.34; b:= true;
- openStrIO( f, s, forOutput);
- writeln( f, i:10, r:10:3, b:5);
- closeStrIO( f, s);
- writeln('The formatted string is:');
- writeln( s);
-
- i:= 0; r:= 0;
- writeln('Testing string to formatted input');
- openStrIO( f, s, forInput);
- read( f, i, r); {tp can't read booleans}
- closeStrIO( f, s);
- writeln('The read variables are:');
- writeln( i:10, r:10:3);
- write('Hit return...'); readln;
- END.
-
-